<?php

namespace sws;

use ErrorException;
use Swoole\Coroutine;
use Throwable;

class Error
{

    protected static $instance;

    /**
     * @return Error
     */
    public static function getInstance(): Error
    {
        if (null === self::$instance) {
            static::$instance = new static();
        }
        return static::$instance;
    }

    /**
     * 注册错误处理
     */
    public function registerErrorHandle()
    {
        set_error_handler([$this, 'appError']);
        set_exception_handler([$this, 'appException']);
        register_shutdown_function([$this, 'appShutdown']);
    }

    /**
     * 错误处理函数（所有错误当做异常处理）
     * @param $errno
     * @param $errstr
     * @param $errfile
     * @param $errline
     * @throws ErrorException
     */
    public function appError($errno, $errstr, $errfile, $errline)
    {
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    }

    /**
     * 进程中止时执行的函数
     * @throws ErrorException
     */
    public function appShutdown()
    {
        if ($e = error_get_last()) {
            $this->appError($e['type'], $e['message'], $e['file'], $e['line']);
        }
    }

    /**
     * 程序异常处理
     * @param $e Throwable
     */
    public function appException(Throwable $e)
    {
        //如果在协层环境，并且是http请求，向客户端发送消息
        if (Coroutine::getCid() > 0 && Container::getInstance()->has('response')) {
            $response = Container::getInstance()->get('response');
            $response->status(500);
            $response->end($e->getMessage());
        }
        Console::getInstance()->writeln($e->__toString(), Console::ERROR);


        //处理后续日志记录

    }


}